﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace Architecture.WCF.Tools.Extensions
{
    public class ClientMessageInspector : IClientMessageInspector
    {
        private const string HEADER_URI_NAMESPACE = "http://www.Architecture.com";
        private const string HEADER_SOURCE_ADDRESS = "Architecture-X-Forwarded-For";

        public ClientMessageInspector()
        {
        }

        public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
        {
        }

        public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
        {

            if (HttpContext.Current != null)
            {
                string adresseIP = "TO FIX";//PortalUser.GetIpAddress(HttpContext.Current);

                HttpRequestMessageProperty property;
                if (!request.Properties.ContainsKey(HttpRequestMessageProperty.Name))
                {
                    property = new HttpRequestMessageProperty();
                    request.Properties.Add(HttpRequestMessageProperty.Name, property);
                }
                else
                {
                    property = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name]; 
                }

                property.Headers.Set(HEADER_SOURCE_ADDRESS, adresseIP);

                MessageHeader header = null;
                try
                {
                    header = MessageHeader.CreateHeader(HEADER_SOURCE_ADDRESS, HEADER_URI_NAMESPACE, adresseIP);
                }
                catch (Exception e)
                {
                    header = MessageHeader.CreateHeader(HEADER_SOURCE_ADDRESS, HEADER_URI_NAMESPACE, null);
                }

                if (request.Headers.FindHeader(HEADER_SOURCE_ADDRESS, HEADER_URI_NAMESPACE) < 0)
                {
                    request.Headers.Add(header);
                }
            }
            else if (OperationContext.Current != null)
            {
                //If service layer does a nested call to another service layer method, ensure that original web caller IP is passed through also 
                MessageHeader header = null;
                int index = OperationContext.Current.IncomingMessageHeaders.FindHeader(HEADER_SOURCE_ADDRESS, HEADER_URI_NAMESPACE);
                if (index > -1)
                {
                    string remoteAddress = OperationContext.Current.IncomingMessageHeaders.GetHeader<String>(index);
                    header = MessageHeader.CreateHeader(HEADER_SOURCE_ADDRESS, HEADER_URI_NAMESPACE, remoteAddress);
                }
                else
                {
                    header = MessageHeader.CreateHeader(HEADER_SOURCE_ADDRESS, HEADER_URI_NAMESPACE, null);
                }

                request.Headers.Add(header);
            }

            return null;

        }
    }
}
